package org.pentaho.di.core.database.util;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.yzbdl.lanius.core.constant.LocalDir;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleDatabaseException;
import org.pentaho.di.core.exception.KettlePluginException;
import org.yzbdl.lanius.core.plugins.ClassLoaderManager;
import org.pentaho.di.core.plugins.PluginInterface;
import org.yzbdl.lanius.core.plugins.metastore.LdrPluginDao;
import org.yzbdl.lanius.core.plugins.metastore.LdrPluginEntity;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.yzbdl.lanius.core.plugins.util.OSinfo;

public class CustomDriverClassLoaderUtil {

    public static ClassLoader getCustomDriverClassLoader(DatabaseMeta databaseMeta, PluginInterface plugin)
        throws KettleDatabaseException {
        File file;
        URL[] urls = {};
        try {
            if (databaseMeta.isUseCustomDriver()) { // 是否使用了自定义驱动
                String driverPath = databaseMeta.getCustomDriverPath();
                if (!OSinfo.WINDOWS) {
                    driverPath = driverPath.replace("\\", "/");
                }
                file = new File(driverPath);
                urls = ArrayUtil.append(urls, file.toURI().toURL());
            } else { // 使用插件配置的驱动
                File drivers = new File(LocalDir.dbDriverFolder);
                if (!drivers.exists()) {
                    throw new KettleDatabaseException("未找到数据库驱动目录。");
                }
                LdrPluginEntity entity = LdrPluginDao.getInstance().getLocalVersionOne(plugin.getId(),
                    plugin.getPluginType().getName(), plugin.getVersion());
                JSONObject jsonObj =
                    StringUtils.isNotBlank(entity.getMetaInfo()) ? JSONUtil.parseObj(entity.getMetaInfo()) : null;
                if (null == jsonObj) {
                    throw new KettleDatabaseException("未找到数据库插件" + plugin.getName() + "的驱动配置。");
                }
                Set<File> collect = Optional.ofNullable(jsonObj)
                    .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("extension")))
                    .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONArray("driver")))
                    .flatMap(jsonArray -> Optional.ofNullable(jsonArray.toList(String.class))).orElseGet(ArrayList::new)
                    .stream().map(one -> new File(LocalDir.dbDriverFolder + File.separator + one))
                    .collect(Collectors.toSet());
                for (File one : collect) {
                    urls = ArrayUtil.append(urls, one.toURI().toURL());
                }
            }
            ClassLoader classLoader = ClassLoaderManager.getInstance().getClassLoader(plugin);
            return CustomDriverClassloader
                .getInstance( urls, classLoader, plugin.getId() + "_" + plugin.getPluginType().getName() +
                    "_" + plugin.getVersion() + "_use_custom_driver_" + databaseMeta.isUseCustomDriver(),
                    databaseMeta.getDriverClass());
        } catch (Exception e) {
            e.printStackTrace();
            try {
                return ClassLoaderManager.getInstance().getClassLoader(plugin);
            } catch (KettlePluginException e1) {
                e1.printStackTrace();
                throw new KettleDatabaseException("加载数据库插件Driver时发生错误", e);
            }
        }
    }

}
